package com.youlu.campus.service.clock;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

/**
 * @author : [dengbo]
 * @className : ActivityClockRedisService
 * @description : [用户活动打卡]
 * @createTime : [2023/5/19 12:01]
 */
@Slf4j
@Data
@Service
public class ActivityClockRedisService {

    public static final String SIGN_KEY = "activityId:%s:userId:%s.clock.record";
    public static final String RE_SIGN_KEY = "activityId:%s:userId:%s.re.clock.record";

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 获取用户签到key
     */
    public String getUserActivityClockKey(String activityId, String userId, boolean sign) {
        if (sign) {
            return String.format(SIGN_KEY, activityId, userId);
        }
        return String.format(RE_SIGN_KEY, activityId, userId);
    }

    /**
     * 用户签到（BitMap 设值）
     */
    public boolean sign(String signKey, int offset) {
        return redisTemplate.opsForValue().setBit(signKey, offset, true);
    }

    /**
     * 获取是否签到（BitMap 取值）
     */
    public boolean getSign(String signKey, int offset) {
        try {
            return redisTemplate.opsForValue().getBit(signKey, offset);
        } catch (Exception e) {
            log.error("获取签到状态异常，key:{}, offset:{}", signKey, offset, e);
            return false;
        }
    }

    /**
     * 获取签到次数（BitMap 位计数）
     */
    public long getSignCount(String signKey) {
        try {
            return redisTemplate.execute(connection -> connection.bitCount(signKey.getBytes()), true);
        } catch (Exception e) {
            log.error("统计签到次数异常，key:{}", signKey, e);
            return 0;
        }
    }

    /**
     * 获取签到列表（BitMap 位域查询）
     * 修正：使用 BitFieldSubCommands 构建命令，解决参数和返回值问题
     */
    public List<Long> getSignList(String signKey, long offset, int num) {
        log.info(":>>> 开始获取签到列表:{},{},{}", signKey, offset, num);
        try {
            // 构建 BITFIELD 命令：GET u{num} {offset}
            BitFieldSubCommands subCommands = BitFieldSubCommands.create()
                    .get(BitFieldSubCommands.BitFieldType.unsigned(num))  // 无符号整数，长度num位
                    .valueAt(offset);  // 从offset位置开始

            // 执行命令并返回结果（List<Long>）
            return redisTemplate.opsForValue().bitField(signKey, subCommands);
        } catch (Exception e) {
            log.error("获取签到列表异常，key:{}, offset:{}, num:{}", signKey, offset, num, e);
            return Arrays.asList();  // JDK8 推荐使用 emptyList() 替代 Collections.emptyList()
        }
    }

}